﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="ConnectionDetail.cs" company="">
//   
// </copyright>
// <summary>
//   Defines the ConnectionDetail type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace ComparisonTool.Connection
{
    using System;
    using System.Xml.Serialization;

    using Microsoft.Xrm.Sdk.Client;

    /// <summary>
    /// The connection detail.
    /// </summary>
    public class ConnectionDetail : IComparable
    {
        /// <summary>
        /// Gets or sets the auth type.
        /// </summary>
        public AuthenticationProviderType AuthType { get; set; }

        /// <summary>
        /// Gets or sets the connection unique identifier
        /// </summary>
        public Guid? ConnectionId { get; set; }

        /// <summary>
        /// Gets or sets the name of the connection
        /// </summary>
        public string ConnectionName { get; set; }

        /// <summary>
        /// Gets or sets a value indicating whether is custom auth.
        /// </summary>
        public bool IsCustomAuth { get; set; }

        /// <summary>
        /// Get or set flag to know if we use IFD
        /// </summary>
        public bool UseIfd { get; set; }

        /// <summary>
        /// Get or set flag to know if we use CRM Online
        /// </summary>
        public bool UseOnline { get; set; }

        /// <summary>
        /// Get or set flag to know if we use Online Services
        /// </summary>
        public bool UseOsdp { get; set; }

        /// <summary>
        /// Get or set the Crm Ticket
        /// </summary>
        [XmlIgnore]
        public string CrmTicket { get; set; }

        /// <summary>
        /// Get or set the user domain name
        /// </summary>
        public string UserDomain { get; set; }

        /// <summary>
        /// Get or set user login
        /// </summary>
        public string UserName { get; set; }

        /// <summary>
        /// Get or set the user password
        /// </summary>
        public string UserPassword { get; set; }

        /// <summary>
        /// Gets or sets a value indicating whether save password.
        /// </summary>
        public bool SavePassword { get; set; }

        /// <summary>
        /// Get or set the use of SSL connection
        /// </summary>
        public bool UseSsl { get; set; }

        /// <summary>
        /// Get or set the server name
        /// </summary>
        public string ServerName { get; set; }

        /// <summary>
        /// Get or set the server port
        /// </summary>
        public string ServerPort { get; set; }

        /// <summary>
        /// Get or set the organization name
        /// </summary>
        public string Organization { get; set; }

        /// <summary>
        /// Get or set the organization name
        /// </summary>
        public string OrganizationUrlName { get; set; }

        /// <summary>
        /// Get or set the organization friendly name
        /// </summary>
        public string OrganizationFriendlyName { get; set; }

        /// <summary>
        /// Gets or sets the Crm Service Url
        /// </summary>
        public string OrganizationServiceUrl { get; set; }

        /// <summary>
        /// Gets or sets the Home realm url for ADFS authentication
        /// </summary>
        public string HomeRealmUrl { get; set; }

        /// <summary>
        /// Gets or sets the organization version.
        /// </summary>
        public string OrganizationVersion { get; set; }

        /// <summary>
        /// Gets the organization major version.
        /// </summary>
        public int OrganizationMajorVersion
        {
            get
            {
                return this.OrganizationVersion != null ? int.Parse(this.OrganizationVersion.Split('.')[0]) : -1;
            }
        }

        /// <summary>
        /// Gets the organization minor version.
        /// </summary>
        public int OrganizationMinorVersion
        {
            get
            {
                return this.OrganizationVersion != null ? int.Parse(this.OrganizationVersion.Split('.')[1]) : -1;
            }
        }

        /// <summary>
        /// Retourne le nom de la connexion
        /// </summary>
        /// <returns>Nom de la connexion</returns>
        public override string ToString()
        {
            return this.ConnectionName;
        }

        /// <summary>
        /// The get discovery crm connection string.
        /// </summary>
        /// <returns>
        /// The <see cref="string"/>.
        /// </returns>
        public string GetDiscoveryCrmConnectionString()
        {
            var connectionString = string.Format(
                "Url={0}://{1}:{2};", 
                this.UseSsl ? "https" : "http", 
                this.UseIfd ? this.ServerName : this.UseOsdp ? "disco." + this.ServerName : this.UseOnline ? "dev." + this.ServerName : this.ServerName, 
                this.ServerPort.Length == 0 ? (this.UseSsl ? 443 : 80) : int.Parse(this.ServerPort));

            if (this.IsCustomAuth)
            {
                if (!this.UseIfd)
                {
                    if (!string.IsNullOrEmpty(this.UserDomain))
                    {
                        connectionString += string.Format("Domain={0};", this.UserDomain);
                    }
                }

                string username = this.UserName;
                if (this.UseIfd)
                {
                    if (!string.IsNullOrEmpty(this.UserDomain))
                    {
                        username = string.Format("{0}\\{1}", this.UserDomain, this.UserName);
                    }
                }

                connectionString += string.Format("Username={0};Password={1};", username, this.UserPassword);
            }

            if (this.UseOnline && !this.UseOsdp)
            {
                // ClientCredentials deviceCredentials;

                // do
                // {
                // deviceCredentials = DeviceIdManager.LoadDeviceCredentials() ??
                // DeviceIdManager.RegisterDevice();
                // } while (deviceCredentials.UserName.Password.Contains(";")
                // || deviceCredentials.UserName.Password.Contains("=")
                // || deviceCredentials.UserName.Password.Contains(" ")
                // || deviceCredentials.UserName.UserName.Contains(";")
                // || deviceCredentials.UserName.UserName.Contains("=")
                // || deviceCredentials.UserName.UserName.Contains(" "));

                // connectionString += string.Format("DeviceID={0};DevicePassword={1};",
                // deviceCredentials.UserName.UserName,
                // deviceCredentials.UserName.Password);
            }

            if (this.UseIfd && !string.IsNullOrEmpty(this.HomeRealmUrl))
            {
                connectionString += string.Format("HomeRealmUri={0};", this.HomeRealmUrl);
            }

            return connectionString;
        }

        /// <summary>
        /// The get organization crm connection string.
        /// </summary>
        /// <returns>
        /// The <see cref="string"/>.
        /// </returns>
        public string GetOrganizationCrmConnectionString()
        {
            // var currentServerName = string.Empty;
            if (this.UseOsdp || this.UseOnline)
            {
                // currentServerName = string.Format("{0}.{1}", this.OrganizationUrlName, this.ServerName);
            }
            else if (this.UseIfd)
            {
                var serverNameParts = this.ServerName.Split('.');

                serverNameParts[0] = this.OrganizationUrlName;

                // currentServerName = string.Format("{0}:{1}",
                // string.Join(".", serverNameParts),
                // this.ServerPort.Length == 0 ? (this.UseSsl ? 443 : 80) : int.Parse(this.ServerPort));
            }
            else
            {
                // currentServerName = string.Format("{0}:{1}/{2}",
                // this.ServerName,
                // this.ServerPort.Length == 0 ? (this.UseSsl ? 443 : 80) : int.Parse(this.ServerPort),
                // this.Organization);
            }

            // var connectionString = string.Format("Url={0}://{1};",
            // UseSsl ? "https" : "http",
            // currentServerName);
            var connectionString = string.Format("Url={0};", this.OrganizationServiceUrl.Replace("/XRMServices/2011/Organization.svc", string.Empty));

            if (this.IsCustomAuth)
            {
                if (!this.UseIfd)
                {
                    if (!string.IsNullOrEmpty(this.UserDomain))
                    {
                        connectionString += string.Format("Domain={0};", this.UserDomain);
                    }
                }

                string username = this.UserName;
                if (this.UseIfd)
                {
                    if (!string.IsNullOrEmpty(this.UserDomain))
                    {
                        username = string.Format("{0}\\{1}", this.UserDomain, this.UserName);
                    }
                }

                connectionString += string.Format("Username={0};Password={1};", username, this.UserPassword);
            }

            if (this.UseOnline)
            {
                // ClientCredentials deviceCredentials;

                // do
                // {
                // deviceCredentials = DeviceIdManager.LoadDeviceCredentials() ??DeviceIdManager.RegisterDevice();
                // } while (deviceCredentials.UserName.Password.Contains(";")
                // || deviceCredentials.UserName.Password.Contains("=")
                // || deviceCredentials.UserName.Password.Contains(" ")
                // || deviceCredentials.UserName.UserName.Contains(";")
                // || deviceCredentials.UserName.UserName.Contains("=")
                // || deviceCredentials.UserName.UserName.Contains(" "));

                // connectionString += string.Format("DeviceID={0};DevicePassword={1};",
                // deviceCredentials.UserName.UserName,
                // deviceCredentials.UserName.Password);
            }

            if (this.UseIfd && !string.IsNullOrEmpty(this.HomeRealmUrl))
            {
                connectionString += string.Format("HomeRealmUri={0};", this.HomeRealmUrl);
            }

            return connectionString;
        }

        /// <summary>
        /// The compare to.
        /// </summary>
        /// <param name="obj">
        /// The obj.
        /// </param>
        /// <returns>
        /// The <see cref="int"/>.
        /// </returns>
        public int CompareTo(object obj)
        {
            return string.CompareOrdinal(this.ConnectionName, ((ConnectionDetail)obj).ConnectionName);
        }
    }
}